import { SyncHook, AsyncParallelHook, SyncBailHook, SyncWaterfallHook, AsyncSeriesHook } from 'tapable'

class Car {
    constructor(){
        this.hooks = {
            // 加速
            acclerate: new SyncHook(['newSpeed']),
            // 刹车
            brake: new SyncHook(),
            // 计算路线，SyncWaterfallHook依赖上一次回调参数
            calculateRoutes: new SyncWaterfallHook(["source", "target", "routesList"]),
            // AsyncParallelHook 异步并行执行&不依赖返回值&多个互不依赖的异步任务需要并行执行的场景
            // calculateRoutes: new AsyncParallelHook(["source", "target", "routesList"])

            /**
             * 计算里程，比如 22 km/h
             * 1 导入 AsyncSeriesHook：确保我们从 tapable 库中导入 AsyncSeriesHook。
             * 2 在 Car 类中创建 calculateMileage 钩子。
             * 3 定义一个方法来调用 calculateMileage 钩子。
             * 4 为 calculateMileage 钩子添加异步监听器。
             * 5 调用钩子并处理结果。
             */
            calculateMileage: new AsyncSeriesHook(['distance', 'fuelUsed']),

            // 计算费用
            calculateCost: new AsyncSeriesHook(['distance'])
        }

    }
    /**
     * 你不会从 SyncHook 或 AsyncParallelHook 获得返回值，为此，请分别使用 SyncWaterfallHook 和 AsyncSeriesWaterfallHook
     * @param {*} newSpeed 
     */
    setSpeed (newSpeed) {
        // 即使您返回值，以下调用也会返回未定义
        this.hooks.acclerate.call(newSpeed)
    }

    stop () {
        this.hooks.brake.call()
    }

    calculateRoutes(source, target) {
        const routesList = [];
        return this.hooks.calculateRoutes.call(source, target, routesList);
    }

    calculateMileage (distance, fuelUsed, callback) {
        this.hooks.calculateMileage.callAsync(distance, fuelUsed, callback);
    }

    calculateCost(distance, callback) {
        return this.hooks.calculateCost.promise(distance)
    }
}

export default Car